#pragma once
#include <KexComm.h>
#include <ShTypes.h>

typedef enum _DEVICE_SCALE_FACTOR {
	DEVICE_SCALE_FACTOR_INVALID	= 0,
	SCALE_100_PERCENT			= 100,
	SCALE_120_PERCENT			= 120,
	SCALE_125_PERCENT			= 125,
	SCALE_140_PERCENT			= 140,
	SCALE_150_PERCENT			= 150,
	SCALE_160_PERCENT			= 160,
	SCALE_175_PERCENT			= 175,
	SCALE_180_PERCENT			= 180,
	SCALE_200_PERCENT			= 200,
	SCALE_225_PERCENT			= 225,
	SCALE_250_PERCENT			= 250,
	SCALE_300_PERCENT			= 300,
	SCALE_350_PERCENT			= 350,
	SCALE_400_PERCENT			= 400,
	SCALE_450_PERCENT			= 450,
	SCALE_500_PERCENT			= 500
} TYPEDEF_TYPE_NAME(DEVICE_SCALE_FACTOR);

typedef enum MONITOR_DPI_TYPE {
	MDT_EFFECTIVE_DPI	= 0,
	MDT_ANGULAR_DPI		= 1,
	MDT_RAW_DPI			= 2,
	MDT_MAXIMUM_DPI		= 3,
	MDT_DEFAULT			= MDT_EFFECTIVE_DPI
} TYPEDEF_TYPE_NAME(MONITOR_DPI_TYPE);

typedef enum _DPI_AWARENESS {
	DPI_AWARENESS_INVALID			= -1,
	DPI_AWARENESS_UNAWARE			= 0,
	DPI_AWARENESS_SYSTEM_AWARE		= 1,
	DPI_AWARENESS_PER_MONITOR_AWARE	= 2,
	DPI_AWARENESS_MAX_VALUE			= 3
} TYPEDEF_TYPE_NAME(DPI_AWARENESS);

typedef enum _PROCESS_DPI_AWARENESS {
	PROCESS_DPI_UNAWARE				= 0,
	PROCESS_SYSTEM_DPI_AWARE		= 1,
	PROCESS_PER_MONITOR_DPI_AWARE	= 2,
	PROCESS_MAX_DPI_AWARENESS		= 3		// always last value
} TYPEDEF_TYPE_NAME(PROCESS_DPI_AWARENESS);

typedef ULONG_PTR DPI_AWARENESS_CONTEXT;

#define DPI_AWARENESS_CONTEXT_UNAWARE				((DPI_AWARENESS_CONTEXT) -1)
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE			((DPI_AWARENESS_CONTEXT) -2)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE		((DPI_AWARENESS_CONTEXT) -3)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2	((DPI_AWARENESS_CONTEXT) -4)
#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED		((DPI_AWARENESS_CONTEXT) -5)

typedef enum _POINTER_INPUT_TYPE {
	PT_POINTER,
	PT_TOUCH,
	PT_PEN,
	PT_MOUSE,
	PT_TOUCHPAD
} POINTER_INPUT_TYPE;

typedef enum _POINTER_BUTTON_CHANGE_TYPE {
	POINTER_CHANGE_NONE,
	POINTER_CHANGE_FIRSTBUTTON_DOWN,
	POINTER_CHANGE_FIRSTBUTTON_UP,
	POINTER_CHANGE_SECONDBUTTON_DOWN,
	POINTER_CHANGE_SECONDBUTTON_UP,
	POINTER_CHANGE_THIRDBUTTON_DOWN,
	POINTER_CHANGE_THIRDBUTTON_UP,
	POINTER_CHANGE_FOURTHBUTTON_DOWN,
	POINTER_CHANGE_FOURTHBUTTON_UP,
	POINTER_CHANGE_FIFTHBUTTON_DOWN,
	POINTER_CHANGE_FIFTHBUTTON_UP
} POINTER_BUTTON_CHANGE_TYPE;

typedef UINT32 POINTER_FLAGS;
#define POINTER_FLAG_NONE               0x00000000 // Default
#define POINTER_FLAG_NEW                0x00000001 // New pointer
#define POINTER_FLAG_INRANGE            0x00000002 // Pointer has not departed
#define POINTER_FLAG_INCONTACT          0x00000004 // Pointer is in contact
#define POINTER_FLAG_FIRSTBUTTON        0x00000010 // Primary action
#define POINTER_FLAG_SECONDBUTTON       0x00000020 // Secondary action
#define POINTER_FLAG_THIRDBUTTON        0x00000040 // Third button
#define POINTER_FLAG_FOURTHBUTTON       0x00000080 // Fourth button
#define POINTER_FLAG_FIFTHBUTTON        0x00000100 // Fifth button
#define POINTER_FLAG_PRIMARY            0x00002000 // Pointer is primary for system
#define POINTER_FLAG_CONFIDENCE         0x00004000 // Pointer is considered unlikely to be accidental
#define POINTER_FLAG_CANCELED           0x00008000 // Pointer is departing in an abnormal manner
#define POINTER_FLAG_DOWN               0x00010000 // Pointer transitioned to down state (made contact)
#define POINTER_FLAG_UPDATE             0x00020000 // Pointer update
#define POINTER_FLAG_UP                 0x00040000 // Pointer transitioned from down state (broke contact)
#define POINTER_FLAG_WHEEL              0x00080000 // Vertical wheel
#define POINTER_FLAG_HWHEEL             0x00100000 // Horizontal wheel
#define POINTER_FLAG_CAPTURECHANGED     0x00200000 // Lost capture
#define POINTER_FLAG_HASTRANSFORM       0x00400000 // Input has a transform associated with it

typedef struct _POINTER_INFO {
	POINTER_INPUT_TYPE         pointerType;
	UINT32                     pointerId;
	UINT32                     frameId;
	POINTER_FLAGS              pointerFlags;
	HANDLE                     sourceDevice;
	HWND                       hwndTarget;
	POINT                      ptPixelLocation;
	POINT                      ptHimetricLocation;
	POINT                      ptPixelLocationRaw;
	POINT                      ptHimetricLocationRaw;
	DWORD                      dwTime;
	UINT32                     historyCount;
	INT32                      InputData;
	DWORD                      dwKeyStates;
	UINT64                     PerformanceCount;
	POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
} POINTER_INFO;

#define POINTER_DEVICE_PRODUCT_STRING_MAX 520

typedef enum _POINTER_DEVICE_TYPE {
	POINTER_DEVICE_TYPE_INTEGRATED_PEN	= 0x00000001,
	POINTER_DEVICE_TYPE_EXTERNAL_PEN	= 0x00000002,
	POINTER_DEVICE_TYPE_TOUCH			= 0x00000003,
	POINTER_DEVICE_TYPE_TOUCH_PAD		= 0x00000004,
	POINTER_DEVICE_TYPE_MAX				= 0xFFFFFFFF
} POINTER_DEVICE_TYPE;

typedef struct _POINTER_DEVICE_INFO {
	DWORD               displayOrientation;
	HANDLE              device;
	POINTER_DEVICE_TYPE pointerDeviceType;
	HMONITOR            monitor;
	ULONG               startingCursorId;
	USHORT              maxActiveContacts;
	WCHAR               productString[POINTER_DEVICE_PRODUCT_STRING_MAX];
} POINTER_DEVICE_INFO;

typedef enum _SHELL_UI_COMPONENT {
	SHELL_UI_COMPONENT_TASKBARS,
	SHELL_UI_COMPONENT_NOTIFICATIONAREA,
	SHELL_UI_COMPONENT_DESKBAND
} TYPEDEF_TYPE_NAME(SHELL_UI_COMPONENT);

typedef enum _ORIENTATION_PREFERENCE {
	ORIENTATION_PREFERENCE_NONE,
	ORIENTATION_PREFERENCE_LANDSCAPE,
	ORIENTATION_PREFERENCE_PORTRAIT,
	ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED,
	ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED
} TYPEDEF_TYPE_NAME(ORIENTATION_PREFERENCE);

typedef enum _AR_STATE {
	AR_ENABLED			= 0x0,
	AR_DISABLED			= 0x1,
	AR_SUPPRESSED		= 0x2,
	AR_REMOTESESSION	= 0x4,
	AR_MULTIMON			= 0x8,
	AR_NOSENSOR			= 0x10,
	AR_NOT_SUPPORTED	= 0x20,
	AR_DOCKED			= 0x40,
	AR_LAPTOP			= 0x80
} TYPEDEF_TYPE_NAME(AR_STATE);

typedef enum _PROCESS_UICONTEXT {
	PROCESS_UICONTEXT_DESKTOP,
	PROCESS_UICONTEXT_IMMERSIVE,
	PROCESS_UICONTEXT_IMMERSIVE_BROKER,
	PROCESS_UICONTEXT_IMMERSIVE_BROWSER
} TYPEDEF_TYPE_NAME(PROCESS_UICONTEXT);

#define PROCESS_UIF_NONE					0
#define PROCESS_UIF_AUTHORING_MODE			1
#define PROCESS_UIF_RESTRICTIONS_DISABLED	2

typedef struct _PROCESS_UICONTEXT_INFORMATION {
	PROCESS_UICONTEXT	UIContext;
	ULONG				Flags;		// PROCESS_UIF_*
} TYPEDEF_TYPE_NAME(PROCESS_UICONTEXT_INFORMATION);

typedef enum _ZBID {
	ZBID_DEFAULT,
	ZBID_DESKTOP,
	ZBID_UIACCESS,
	ZBID_IMMERSIVE_IHM,
	ZBID_IMMERSIVE_NOTIFICATION,
	ZBID_IMMERSIVE_APPCHROME,
	ZBID_IMMERSIVE_MOGO,
	ZBID_IMMERSIVE_EDGY,
	ZBID_IMMERSIVE_INACTIVEMOBODY,
	ZBID_IMMERSIVE_INACTIVEDOCK,
	ZBID_IMMERSIVE_ACTIVEMOBODY,
	ZBID_IMMERSIVE_ACTIVEDOCK,
	ZBID_IMMERSIVE_BACKGROUND,
	ZBID_IMMERSIVE_SEARCH,
	ZBID_GENUINE_WINDOWS
} TYPEDEF_TYPE_NAME(ZBID);

typedef enum tagINPUT_MESSAGE_DEVICE_TYPE {
	IMDT_UNAVAILABLE	= 0x00000000,
	IMDT_KEYBOARD		= 0x00000001,
	IMDT_MOUSE			= 0x00000002,
	IMDT_TOUCH			= 0x00000004,
	IMDT_PEN			= 0x00000008,
	IMDT_TOUCHPAD		= 0x00000010
} INPUT_MESSAGE_DEVICE_TYPE;

typedef enum tagINPUT_MESSAGE_ORIGIN_ID {
	IMO_UNAVAILABLE	= 0x00000000,
	IMO_HARDWARE	= 0x00000001,
	IMO_INJECTED	= 0x00000002,
	IMO_SYSTEM		= 0x00000004
} INPUT_MESSAGE_ORIGIN_ID;

typedef struct _INPUT_MESSAGE_SOURCE {
	INPUT_MESSAGE_DEVICE_TYPE	DeviceType;
	INPUT_MESSAGE_ORIGIN_ID		OriginId;
} TYPEDEF_TYPE_NAME(INPUT_MESSAGE_SOURCE);

//
// pointer.c
//

BOOL WINAPI GetPointerDevices(
	IN OUT	UINT32				*DeviceCount,
	OUT		POINTER_DEVICE_INFO	*PointerDevices);

BOOL WINAPI GetPointerType(
	IN	DWORD				PointerId,
	OUT	POINTER_INPUT_TYPE	*PointerType);

BOOL WINAPI GetPointerInfo(
	IN	DWORD			PointerId,
	OUT	POINTER_INFO	*PointerInfo);

BOOL WINAPI GetPointerTouchInfo(
	IN	DWORD	PointerId,
	OUT	LPVOID	TouchInfo);

BOOL WINAPI GetPointerFrameTouchInfo(
	IN		DWORD	PointerId,
	IN OUT	LPDWORD PointerCount,
	OUT		LPVOID	TouchInfo);

BOOL WINAPI GetPointerFrameTouchInfoHistory(
	IN		DWORD	PointerId,
	IN OUT	DWORD	EntriesCount,
	IN OUT	LPDWORD PointerCount,
	OUT		LPVOID	TouchInfo);

BOOL WINAPI GetPointerPenInfo(
	IN	DWORD	PointerId,
	OUT	LPVOID	PenInfo);

BOOL WINAPI GetPointerPenInfoHistory(
	IN		DWORD	PointerId,
	IN OUT	LPDWORD	EntriesCount,
	OUT		LPVOID	PenInfo);

BOOL WINAPI SkipPointerFrameMessages(
	IN	DWORD	PointerId);

BOOL WINAPI GetPointerDeviceRects(
	IN	HANDLE	Device,
	OUT	LPRECT	PointerDeviceRect,
	OUT	LPRECT	DisplayRect);

BOOL WINAPI EnableMouseInPointer(
	IN	BOOL	Enable);

//
// scaling.c
//

KXUSERAPI DPI_AWARENESS GetAwarenessFromDpiAwarenessContext(
	IN	DPI_AWARENESS_CONTEXT	Value);

KXUSERAPI BOOL WINAPI IsValidDpiAwarenessContext(
	IN	DPI_AWARENESS_CONTEXT	Value);

KXUSERAPI DPI_AWARENESS_CONTEXT WINAPI GetThreadDpiAwarenessContext(
	VOID);

KXUSERAPI DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext(
	IN	DPI_AWARENESS_CONTEXT DpiContext);

KXUSERAPI BOOL WINAPI SetProcessDpiAwarenessContext(
	IN	DPI_AWARENESS_CONTEXT	DpiContext);

KXUSERAPI DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext(
	IN	HWND	Window);

KXUSERAPI HRESULT WINAPI GetProcessDpiAwareness(
	IN	HANDLE					ProcessHandle,
	OUT	PROCESS_DPI_AWARENESS	*DpiAwareness);

KXUSERAPI HRESULT WINAPI SetProcessDpiAwareness(
	IN	PROCESS_DPI_AWARENESS	DpiAwareness);

KXUSERAPI BOOL WINAPI SetProcessDpiAwarenessInternal(
	IN	PROCESS_DPI_AWARENESS	DpiAwareness);

KXUSERAPI HRESULT WINAPI GetDpiForMonitor(
	IN	HMONITOR			Monitor,
	IN	MONITOR_DPI_TYPE	DpiType,
	OUT	PULONG				DpiX,
	OUT	PULONG				DpiY);

KXUSERAPI HRESULT WINAPI GetScaleFactorForMonitor(
	IN	HMONITOR				Monitor,
	OUT	PDEVICE_SCALE_FACTOR	ScaleFactor);

KXUSERAPI UINT WINAPI GetDpiForSystem(
	VOID);

KXUSERAPI UINT WINAPI GetDpiForWindow(
	IN	HWND	Window);

KXUSERAPI BOOL WINAPI AdjustWindowRectExForDpi(
	IN OUT	LPRECT	Rect,
	IN		ULONG	WindowStyle,
	IN		BOOL	HasMenu,
	IN		ULONG	WindowExStyle,
	IN		ULONG	Dpi);

KXUSERAPI UINT WINAPI GetDpiForShellUIComponent(
	IN	SHELL_UI_COMPONENT	component);

KXUSERAPI BOOL WINAPI LogicalToPhysicalPointForPerMonitorDPI(
	IN		HWND	Window,
	IN OUT	LPPOINT	Point);

KXUSERAPI BOOL WINAPI PhysicalToLogicalPointForPerMonitorDPI(
	IN		HWND	Window,
	IN OUT	LPPOINT	Point);

KXUSERAPI BOOL WINAPI EnableNonClientDpiScaling(
	IN	HWND	Window);

//
// sysmetrc.c
//

INT WINAPI GetSystemMetricsForDpi(
	IN	INT		Index,
	IN	UINT	Dpi);

BOOL WINAPI SystemParametersInfoForDpi(
	IN		UINT	Action,
	IN		UINT	Parameter,
	IN OUT	PVOID	Data,
	IN		UINT	WinIni,
	IN		UINT	Dpi);

//
// pwrnotfy.c
//

KXUSERAPI BOOL WINAPI RegisterSuspendResumeNotification(
	IN	HANDLE	Recipient,
	IN	ULONG	Flags);

KXUSERAPI BOOL WINAPI UnregisterSuspendResumeNotification(
	IN OUT	HPOWERNOTIFY	Handle);

//
// misc.c
//

KXUSERAPI BOOL WINAPI IsImmersiveProcess(
	IN	HANDLE	ProcessHandle);